package com.huike.clues.service.impl;

import com.huike.clues.mapper.SysDeptMapper;
import com.huike.clues.mapper.SysRoleDeptMapper;
import com.huike.clues.mapper.SysRoleMapper;
import com.huike.clues.mapper.SysUserMapper;
import com.huike.clues.service.ISysDeptService;
import com.huike.clues.service.ISysRoleService;
import com.huike.common.core.controller.BaseController;
import com.huike.common.core.domain.TreeSelect;
import com.huike.common.core.domain.entity.SysDept;
import com.huike.common.core.domain.entity.SysRole;
import com.huike.common.core.domain.entity.SysUser;
import com.huike.common.core.page.TableDataInfo;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import com.huike.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.huike.clues.domain.SysRoleDept;
import com.huike.clues.mapper.SysDeptMapper;
import com.huike.clues.mapper.SysRoleDeptMapper;
import com.huike.clues.service.ISysDeptService;
import com.huike.common.core.domain.TreeSelect;
import com.huike.common.core.domain.entity.SysDept;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SysDeptServiceImpl extends BaseController implements ISysDeptService {
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private ISysRoleService iSysRoleService;


    @Resource
    private SysRoleDeptMapper roleDeptMapper;


    /**
     * 新增部门 子部门递归
     *
     * @param sysDept
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertDept(SysDept sysDept) {
        //公共字段填充
        String username = SecurityUtils.getUsername();
        Date date = DateUtils.getNowDate();
        sysDept.setCreateBy(username);
        sysDept.setUpdateBy(username);
        sysDept.setCreateTime(date);
        sysDept.setUpdateTime(date);
        if (sysDept.getOrderNum() == null) {
            Integer count = sysDeptMapper.countDept() + 1;
            sysDept.setOrderNum(count.toString());
        }
        //sys_dept插入数据
        sysDeptMapper.insertDept(sysDept);
        //sys_user插入数据
        List<SysUser> users = sysDept.getUsers();
        if (users != null && users.size() != 0) {
            //公共字段填充
            users.forEach(e -> {
                List<SysRole> roles = e.getRoles();
                if (roles != null || roles.size() != 0) {
                    roles.forEach(role ->
                            //sys_roles插入数据
                            iSysRoleService.insertRole(role));
                    e.setCreateBy(username);
                    e.setUpdateBy(username);
                    e.setCreateTime(date);
                    e.setUpdateTime(date);
                    //sys_user插入数据
                    sysUserMapper.insertUser(e);
                }
            });
        }
        //子部门 插入 递归
        List<SysDept> children = sysDept.getChildren();
        if (children != null && children.size() != 0) {
            children.forEach(this::insertDept);
        }

    }

    /**
     * 修改部门
     *
     * @param sysDept
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDept(SysDept sysDept) {
        //公共字段填充
        String username = SecurityUtils.getUsername();
        Date date = DateUtils.getNowDate();
        sysDept.setUpdateBy(username);
        sysDept.setUpdateTime(date);
        sysDeptMapper.updateDept(sysDept);
        List<SysUser> users = sysDept.getUsers();
        if (users != null && users.size() != 0) {
            //公共字段填充
            users.forEach(e -> {
                //删除用户表相关数据
                sysUserMapper.deleteUserById(e.getUserId());
                List<SysRole> roles = e.getRoles();
                if (roles != null && roles.size() != 0) {
                    roles.forEach(role -> iSysRoleService.updateRole(role));
                }
                e.setCreateBy(username);
                e.setUpdateBy(username);
                e.setCreateTime(date);
                e.setUpdateTime(date);
                //sys_user插入数据
                sysUserMapper.insertUser(e);
            });
        }
        //子部门 修改 递归
        List<SysDept> children = sysDept.getChildren();
        if (children != null && children.size() != 0) {
            children.forEach(this::updateDept);
        }
    }
    //todo del_flag to long

    @Override
    public TableDataInfo listDept(SysDept sysDept) {
        startPage();
        List<SysDept> rows = sysDeptMapper.listDept(sysDept);
        rows.forEach(e -> {
            Long deptId = sysDept.getDeptId();
            //查询子部门
            List<SysDept> sonList = sysDeptMapper.listDeptByparentId(deptId);
            e.setChildren(sonList);
            //查询用户
            List<SysUser> users = sysUserMapper.listUserByparentId(deptId);
            users.forEach(user -> {
                //查询角色
                List<SysRole> sysRoles = sysRoleMapper.selectRolePermissionByUserId(user.getUserId());
                user.setRoles(sysRoles);
            });
            e.setUsers(users);
        });
        return getDataTable(rows);
    }




    @Override
    public SysDept findDeptByDeptId(Long deptId) {
        return sysDeptMapper.findDeptByDeptId(deptId);
    }

    @Override
    public int deleteDeptByDeptId(Long deptId) {
        return sysDeptMapper.deleteDeptByDeptId(deptId);
    }

    /**
     * 进行递归
     *
     * @param depts
     * @param dept
     */
    private void recursionFn(List<SysDept> depts, SysDept dept) {
        List<SysDept> childList = getChildList(depts, dept);
        dept.setChildren(childList);

        for (SysDept child : childList) {
            if (childList.size() > 0) {
                recursionFn(depts, child);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
        List<SysDept> tlist = new ArrayList<SysDept>();
        Iterator<SysDept> it = list.iterator();
        while (it.hasNext()) {
            SysDept n = (SysDept) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 获取前端所需部门下拉树
     * 首先通过 deptMapper.treeSelect获取 部门下拉树列表
     * 然后进行构建部门的树结构
     * 为了防止子节点的子节点没有被查询 这里写了多个循环 代码上可能比较冗余 待优化
     * 思路: 如果是根节点 那么直接 遍历所有初级子节点
     * 如果当前节点下 非空时, 继续循环遍历节点
     * 如果当前节点下 为空时,说明循环结束 返回上一节点
     * 直到回到根节点
     *
     * @param sysDept
     * @return
     */
    @Override
    public List<SysDept> treeSelect(SysDept sysDept) {
        List<SysDept> depts = sysDeptMapper.treeSelect(sysDept);

        //构建部门树结构
        List<SysDept> returnList = new ArrayList<SysDept>();
        List<Long> tempList = new ArrayList<Long>();

        for (SysDept dept : depts) {
            tempList.add(dept.getDeptId());
        }

        for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext(); ) {
            SysDept dept = (SysDept) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }

            if (returnList.isEmpty()) {
                returnList = depts;
            }
        }
        return returnList;
    }


    /**
     * 根据用户id获取其对应的所有部门id集合
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> selectByRoleId(Integer roleId) {
        //由角色id获取它所属的所有部门id
        List<Integer> deptIds = roleDeptMapper.selectByRoleId(roleId);
        return deptIds;
    }

    /**
     * 根据id获取所有部门
     *
     * @param deptIds
     * @return
     */
    @Override
    public List<SysDept> selectByIds(List<Integer> deptIds) {
        List<SysDept> deptList = sysDeptMapper.selectByIds(deptIds);
        return deptList;
    }

    /**
     * 根据部门集合获取部门列表树
     *
     * @param deptList
     * @return
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> deptList) {
        List<SysDept> treeList = new ArrayList<>();
        for (SysDept dept : deptList) {
            if (dept.getParentId() != null) {
                recursionGetChildren(deptList, dept);
                treeList.add(dept);
            }
        }
        List<TreeSelect> treeSelectList = new ArrayList<>();
        for (SysDept dept : treeList) {
            TreeSelect treeSelect = new TreeSelect(dept);
            treeSelectList.add(treeSelect);
        }
        return treeSelectList;
    }

    /**
     * 得到部门的所有子部门
     *
     * @param deptList
     * @param dept
     * @return
     */
    public List<SysDept> getChildren(List<SysDept> deptList, SysDept dept) {

        List<SysDept> childrenDeptList = new ArrayList<>();
        for (SysDept sd : deptList) {
            if (sd.getParentId() != null && sd.getParentId() == dept.getDeptId()) {
                childrenDeptList.add(sd);
            }
        }
        return childrenDeptList;
    }

    /**
     * 循环遍历得到子部门
     *
     * @param deptList
     * @param dept
     */
    public void recursionGetChildren(List<SysDept> deptList, SysDept dept) {
        List<SysDept> childrenDeptList = getChildren(deptList, dept);
        dept.setChildren(childrenDeptList);
        for (SysDept sd : childrenDeptList) {
            if (getChildren(deptList, sd).size() > 0) {
                recursionGetChildren(deptList, sd);
            }
        }
    }

    /**
     * 查询部门列表（排除节点）
     *
     * @param dept
     */
    @Override
    public List<SysDept> selectDeptList(SysDept dept) {

        return sysDeptMapper.selectDeptList(dept);

    }
}
